package com.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.config.Constant;
import com.config.URLConstant;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiCspaceAddRequest;
import com.dingtalk.api.request.OapiCspaceGetCustomSpaceRequest;
import com.dingtalk.api.request.OapiCspaceGrantCustomSpaceRequest;
import com.dingtalk.api.request.OapiFileUploadSingleRequest;
import com.dingtalk.api.request.OapiProcessinstanceCreateRequest;
import com.dingtalk.api.request.OapiProcessinstanceCspaceInfoRequest;
import com.dingtalk.api.request.OapiProcessinstanceGetRequest;
import com.dingtalk.api.request.OapiUserGetRequest;
import com.dingtalk.api.request.OapiUserGetuserinfoRequest;
import com.dingtalk.api.response.OapiCspaceAddResponse;
import com.dingtalk.api.response.OapiCspaceGetCustomSpaceResponse;
import com.dingtalk.api.response.OapiCspaceGrantCustomSpaceResponse;
import com.dingtalk.api.response.OapiFileUploadSingleResponse;
import com.dingtalk.api.response.OapiProcessinstanceCreateResponse;
import com.dingtalk.api.response.OapiProcessinstanceCspaceInfoResponse;
import com.dingtalk.api.response.OapiProcessinstanceGetResponse;
import com.dingtalk.api.response.OapiProcessinstanceGetResponse.ProcessInstanceTopVo;
import com.dingtalk.api.response.OapiUserGetResponse;
import com.dingtalk.api.response.OapiUserGetuserinfoResponse;
import com.enums.ProcessResult;
import com.enums.ProcessStatus;
import com.model.ProcessInstanceVO;
import com.model.UploadQuery;
import com.model.UploadVO;
import com.service.ProcessInstanceService;
import com.taobao.api.ApiException;
import com.taobao.api.FileItem;
import com.taobao.api.internal.util.WebUtils;
import com.util.AuthHelper;
import com.util.FileUtils;
import com.util.ServiceResult;

/**
 * 企业 E应用解决方案示例代码 实现了最简单的免密登录（免登）功能
 */
@RestController
public class IndexController {
    private static final Logger bizLogger = LoggerFactory.getLogger(IndexController.class);
    
    @Autowired
    private ProcessInstanceService processInstanceService;

    /**
     * 欢迎页面,通过url访问，判断后端服务是否启动
     */
    @RequestMapping(value = "/welcome", method = RequestMethod.GET)
    public String welcome() {
        return "welcome";
    }

    /**
     * app-main
     */
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public ModelAndView appmain(HttpServletRequest request) {
        ModelAndView modelAndView = new ModelAndView("app-main");
        // modelAndView.addObject("config", AuthHelper.getConfig(request));
        return modelAndView;
    }
    
    /**
     * app-province-list
     */
    @RequestMapping(value = "/province", method = RequestMethod.GET)
    public ModelAndView appProvinceList(HttpServletRequest request) {
        ModelAndView modelAndView = new ModelAndView("app-province-list");
        // modelAndView.addObject("config", AuthHelper.getConfig(request));
        return modelAndView;
    }
    
    /**
     * app-province-list
     */
    @RequestMapping(value = "/province/list", method = RequestMethod.GET)
    @ResponseBody
    public List<ProcessInstanceVO> provinceList(HttpServletRequest request) {
        List<ProcessInstanceVO> listAllProcessInstance = processInstanceService.listAllProcessInstance();
        // 处理枚举
        if (!CollectionUtils.isEmpty(listAllProcessInstance)) {
            for (ProcessInstanceVO vo : listAllProcessInstance) {
                vo.setStatus(ProcessStatus.getText(vo.getStatus()));
                vo.setResult(ProcessResult.getText(vo.getResult()));
                vo.setDownload_url(StringUtils.join(new String[] {Constant.CALLBACK_URL_HOST,vo.getDownload_url()}));
            }
        }
        return listAllProcessInstance;
    }

    /**
     * 上传
     * 
     * @throws ApiException
     */
    @PostMapping(value = "/upload")
    public ServiceResult<UploadVO> upload(@RequestParam(value = "file") MultipartFile file,UploadQuery query) throws IOException, ApiException {
        String serverPath = FileUtils.store(file);
        bizLogger.info("********************************************************:"+serverPath);
        /* // 上传到钉钉媒体服务器1 DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/media/upload");
         * OapiMediaUploadRequest request = new OapiMediaUploadRequest(); String contentType =
         * FileUtils.getFileType(file.getContentType()); request.setType(contentType); request.setMedia(new
         * FileItem(serverPath)); OapiMediaUploadResponse response = client.execute(request,
         * AuthHelper.getAccessToken()); if (response.getErrcode().intValue() != 0) { return
         * ServiceResult.failure(response.getErrorCode(), response.getErrmsg()); }
         * System.out.println("*********************111**************************"); */

        
//        System.out.println("hhahaha");
//        if (1==1) {
//            return null;
//        }
        // 上传2
        OapiFileUploadSingleRequest request = new OapiFileUploadSingleRequest();
        request.setFileSize(FileUtils.getFileSize(serverPath));
        request.setAgentId(Constant.AGENTID.toString());
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/file/upload/single?"
                + WebUtils.buildQuery(request.getTextParams(), "utf-8"));
        // 必须重新new一个请求
        request = new OapiFileUploadSingleRequest();
        request.setFile(new FileItem(serverPath));
        OapiFileUploadSingleResponse response = client.execute(request, AuthHelper.getAccessToken());
        if (response.getErrcode().intValue() != 0) {
            return ServiceResult.failure(response.getErrorCode(), response.getErrmsg());
        }
        System.out.println("*********************111**************************");

        // 申请spaceid
        client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/processinstance/cspace/info");
        OapiProcessinstanceCspaceInfoRequest req = new OapiProcessinstanceCspaceInfoRequest();
        req.setUserId("manager4547");
        OapiProcessinstanceCspaceInfoResponse rsp = client.execute(req, AuthHelper.getAccessToken());
        if (rsp.getErrcode().intValue() != 0) {
            return ServiceResult.failure(rsp.getErrorCode(), rsp.getErrmsg());
        }
        Long spaceid = rsp.getResult().getSpaceId();
        String mediaId = response.getMediaId();
        System.out.println("*********************222**************************");
        // 将该文件添加到顶盘，获得各种id
        client = new DefaultDingTalkClient("https://oapi.dingtalk.com/cspace/add");
        OapiCspaceAddRequest request2 = new OapiCspaceAddRequest();
        request2.setAgentId(Constant.AGENTID.toString());
        request2.setCode(query.getCode());
        request2.setMediaId(mediaId);
        request2.setSpaceId(spaceid.toString());
        request2.setFolderId("0");
        request2.setName(file.getOriginalFilename());
        request2.setOverwrite(true);
        request2.setHttpMethod("GET");
        OapiCspaceAddResponse response2 = client.execute(request2, AuthHelper.getAccessToken());
        System.out.println("*********************333**************************");
        if (StringUtils.isNotBlank(response2.getErrorCode()) && response2.getErrcode().intValue() != 0) {
            return ServiceResult.failure(response2.getErrorCode(), response2.getErrmsg());
        }
        System.out.println("*********************444**************************");
        JSONObject dentry = JSON.parseObject(response2.getDentry());
        UploadVO uploadVO = new UploadVO();
        uploadVO.setFileId(dentry.getString("id"));
        uploadVO.setFileName(dentry.getString("name"));
        uploadVO.setFileSize(dentry.getLong("size"));
        String extension = FilenameUtils.getExtension(dentry.getString("name"));
        uploadVO.setFileType(extension);
        uploadVO.setSpaceId(spaceid.toString());
        System.out.println(JSON.toJSONString(uploadVO));

        // 发起审批
        client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/processinstance/create");
        OapiProcessinstanceCreateRequest request3 = new OapiProcessinstanceCreateRequest();
        request3.setAgentId(Constant.AGENTID);
        request3.setProcessCode("PROC-A58FB763-8AB6-4A50-B3D1-7265EF6C4ABD");
        // 审批流表单参数，设置各表单项值
        List<OapiProcessinstanceCreateRequest.FormComponentValueVo> formComponentValues = new ArrayList<OapiProcessinstanceCreateRequest.FormComponentValueVo>();

        // 单行输入框
        OapiProcessinstanceCreateRequest.FormComponentValueVo vo1 = new OapiProcessinstanceCreateRequest.FormComponentValueVo();
        vo1.setName("测试1");
        vo1.setValue(query.getTest1());
        
        // 单行输入框
        OapiProcessinstanceCreateRequest.FormComponentValueVo vo2 = new OapiProcessinstanceCreateRequest.FormComponentValueVo();
        vo2.setName("测试2");
        vo2.setValue(query.getTest2());
        
        // 附件
        OapiProcessinstanceCreateRequest.FormComponentValueVo attachmentComponent = new OapiProcessinstanceCreateRequest.FormComponentValueVo();
        JSONObject attachmentJson = new JSONObject();
        attachmentJson.put("fileId", uploadVO.getFileId());
        attachmentJson.put("fileName", uploadVO.getFileName());
        attachmentJson.put("fileType", uploadVO.getFileType());
        attachmentJson.put("spaceId", uploadVO.getSpaceId());
        attachmentJson.put("fileSize", uploadVO.getFileSize());

        JSONArray array = new JSONArray();
        array.add(attachmentJson);
        attachmentComponent.setValue(array.toJSONString());
        attachmentComponent.setName("附件");
        // 添加单行输入框、多行输入框、图片、明细、附件到表单
        formComponentValues.add(vo1);
        formComponentValues.add(vo2);
        formComponentValues.add(attachmentComponent);

        request3.setFormComponentValues(formComponentValues);
        // 使用后台模版的情况下不用填写
        // request.setApprovers("userid1,userid2");
        request3.setOriginatorUserId("manager4547");
        request3.setDeptId(-1L);
        // request.setCcList("userid1,userid2");
        request3.setCcPosition("START_FINISH");
        try {
            OapiProcessinstanceCreateResponse response3 = client.execute(request3, AuthHelper.getAccessToken());
            if (response3.getErrcode().intValue() == 0) {
                bizLogger.info("apply process success!!!!");
                String processInstanceId = response3.getProcessInstanceId();
                DingTalkClient client3 = new DefaultDingTalkClient(
                        "https://oapi.dingtalk.com/topapi/processinstance/get");
                OapiProcessinstanceGetRequest request5 = new OapiProcessinstanceGetRequest();
                request5.setProcessInstanceId(processInstanceId);
                OapiProcessinstanceGetResponse response5 = client3.execute(request5, AuthHelper.getAccessToken());
                if (response5.getErrcode().intValue() == 0) {
                    ProcessInstanceTopVo processInstance = response5.getProcessInstance();
                    ProcessInstanceVO vo = new ProcessInstanceVO();
                    vo.setOriginator_dept_id(processInstance.getOriginatorDeptId());
                    vo.setOriginator_userid(processInstance.getOriginatorUserid());
                    vo.setResult(processInstance.getResult());
                    vo.setStatus(processInstance.getStatus());
                    vo.setTitle(processInstance.getTitle());
                    vo.setCreate_time(processInstance.getCreateTime());
                    vo.setFinish_time(processInstance.getFinishTime());
                    vo.setProcessInstanceId(processInstanceId);
                    // 保存附件的相对地址
                    vo.setDownload_url(serverPath);
                    processInstanceService.insert(vo);
                    bizLogger.info("processinstance insert!!!!");
                }
            } else {
                bizLogger.error(response3.getErrmsg());
            }
        } catch (ApiException e) {
            e.printStackTrace();
        }

        return ServiceResult.success(uploadVO);
    }

    /**
     * JSAPI 鉴权
     */
    @RequestMapping(value = "/getJsTicket", method = RequestMethod.GET)
    public ServiceResult getJsTicket(HttpServletRequest request) {
        Map<String, Object> config = AuthHelper.getConfig(request);
        if ((int) config.get("status") == 1) {
            return ServiceResult.success(config);
        }
        return ServiceResult.failure("E.GETJSTICKET.FAILURE");
    }

    /**
     * 获取审批盯盘空间
     */
    @RequestMapping(value = "/getProcessSpaceId", method = RequestMethod.GET)
    public ServiceResult getProcessSpaceId(HttpServletRequest request) {
        DingTalkClient client = new DefaultDingTalkClient(
                "https://oapi.dingtalk.com/topapi/processinstance/cspace/info");
        OapiProcessinstanceCspaceInfoRequest req = new OapiProcessinstanceCspaceInfoRequest();
        req.setUserId("manager4547");
        OapiProcessinstanceCspaceInfoResponse rsp;
        try {
            rsp = client.execute(req, AuthHelper.getAccessToken());
            if (rsp.getErrcode().intValue() == 0) {
                return ServiceResult.success(rsp.getResult().getSpaceId());
            }
        } catch (ApiException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return ServiceResult.failure("");
    }

    /**
     * 获取企业自定义盯盘空间，并授权上传
     * 
     * @throws ApiException
     */
    @RequestMapping(value = "/grantCustomSpace", method = RequestMethod.GET)
    public ServiceResult grantCustomSpace() throws ApiException {
        // 获取spaceid
        DingTalkClient client1 = new DefaultDingTalkClient("https://oapi.dingtalk.com/cspace/get_custom_space");
        OapiCspaceGetCustomSpaceRequest request = new OapiCspaceGetCustomSpaceRequest();
        request.setAgentId(Constant.AGENTID.toString());
        request.setDomain("test");
        request.setHttpMethod("GET");
        OapiCspaceGetCustomSpaceResponse response = client1.execute(request, AuthHelper.getAccessToken());
        if (response.getErrcode() == 0) {
            // 授权上传
            DingTalkClient client2 = new DefaultDingTalkClient("https://oapi.dingtalk.com/cspace/grant_custom_space");
            OapiCspaceGrantCustomSpaceRequest request2 = new OapiCspaceGrantCustomSpaceRequest();
            request2.setAgentId(Constant.AGENTID.toString());
            request2.setDomain("test");
            request2.setType("add");
            request2.setUserid("manager4547");
            request2.setPath("/");
            request2.setDuration(1000L);
            request2.setHttpMethod("GET");
            OapiCspaceGrantCustomSpaceResponse response2 = client2.execute(request2, AuthHelper.getAccessToken());
            return ServiceResult.success(response.getSpaceid());
        }

        return ServiceResult.failure("");
    }

    /**
     * 授权下载预览
     * 
     * @throws ApiException
     */
    @RequestMapping(value = "/grantDownload/{fileid}", method = RequestMethod.GET)
    public ServiceResult grantDownload(@PathVariable("fileid") String fileid) throws ApiException {
        DingTalkClient client2 = new DefaultDingTalkClient("https://oapi.dingtalk.com/cspace/grant_custom_space");
        OapiCspaceGrantCustomSpaceRequest request2 = new OapiCspaceGrantCustomSpaceRequest();
        request2.setAgentId(Constant.AGENTID.toString());
        request2.setDomain("test");
        request2.setType("download");
        request2.setUserid("manager4547");
        request2.setFileids(fileid);
        request2.setPath("/");
        request2.setDuration(1000L);
        request2.setHttpMethod("GET");
        OapiCspaceGrantCustomSpaceResponse response2 = client2.execute(request2, AuthHelper.getAccessToken());

        return ServiceResult.success("");
    }

    /**
     * 钉钉用户登录，显示当前登录用户的userId和名称
     *
     * @param requestAuthCode 免登临时code
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    @ResponseBody
    public ServiceResult login(@RequestParam(value = "authCode") String requestAuthCode) {
        // 获取accessToken,注意正是代码要有异常流处理
        String accessToken = AuthHelper.getAccessToken();

        // 获取用户信息
        DingTalkClient client = new DefaultDingTalkClient(URLConstant.URL_GET_USER_INFO);
        OapiUserGetuserinfoRequest request = new OapiUserGetuserinfoRequest();
        request.setCode(requestAuthCode);
        request.setHttpMethod("GET");

        OapiUserGetuserinfoResponse response;
        try {
            response = client.execute(request, accessToken);
        } catch (ApiException e) {
            e.printStackTrace();
            return null;
        }
        // 3.查询得到当前用户的userId
        // 获得到userId之后应用应该处理应用自身的登录会话管理（session）,避免后续的业务交互（前端到应用服务端）每次都要重新获取用户身份，提升用户体验
        String userId = response.getUserid();

        OapiUserGetResponse userProfile = getUserProfile(accessToken, userId);
        String userName = userProfile.getName();
        Long deptId = userProfile.getDepartment().get(0);
        // 审批里的部门id，1和-1要互相转换一下
        if (deptId.longValue() == 1L) {
            deptId = -1L;
        }
        // 返回结果
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("userId", userId);
        resultMap.put("userName", userName);
        resultMap.put("deptId", deptId);
        ServiceResult serviceResult = ServiceResult.success(resultMap);
        return serviceResult;
    }

    /**
     * 获取用户详情
     *
     * @param accessToken
     * @param userId
     * @return
     */
    private OapiUserGetResponse getUserProfile(String accessToken, String userId) {
        try {
            DingTalkClient client = new DefaultDingTalkClient(URLConstant.URL_USER_GET);
            OapiUserGetRequest request = new OapiUserGetRequest();
            request.setUserid(userId);
            request.setHttpMethod("GET");
            OapiUserGetResponse response = client.execute(request, accessToken);

            return response;
        } catch (ApiException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void main(String[] args) {

    }
}
